/*
 * @(#)Configure.java 2010-7-12
 * 
 * Copyright 5jxiang . All rights reserved.
 */
package com.jz.util;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;



/**
 * <p>
 * <a href="Configure.java.html"><i>View Source</i></a>
 * </p>
 *
 * @author 5jxiang
 * @version $Id$
 */
public class Configure {
//~ Static fields/initializers =============================================
	
	private static final String PLACEHOLDER_PREFIX = "${";
	private static final String PLACEHOLDER_SUFFIX = "}";
	
	//~ Instance fields ========================================================

	private Properties props;
	private Map<String, Object> cache = new HashMap<String, Object>();
	private Map<String, String> variables;
	
	
	//~ Constructors ===========================================================

	private static Configure instance = null;
	
	public static Configure getInstance() {
		return instance;
	}
	
	private Configure(String file, Map<String, String> variables) {
		this.variables = variables;
		props = new Properties();

		InputStream stream = null;
        // Load settings
        try {
        	stream = new FileInputStream(file);
            props.load(stream);
        } catch (IOException e) {
            throw new RuntimeException("Could not load " + file + e);
        } finally {
        	if (stream != null) {
        		try {
					stream.close();
				} catch (IOException e) {}
        	}
        }
	}
	
	//~ Methods ================================================================
	
	public static void initialize(String file, Map<String, String> variables) {
		instance = new Configure(file, variables);
	}
	
	public static String get(String key) {
		return get(key, null);
	}
	
	public static String get(String key, String defaultValue) {
		return getInstance()._get(key, defaultValue);
	}
	
	public String _get(String key, String defaultValue) {
		if (cache.containsKey(key)) {
			return (String) cache.get(key);
		}
		
		String value = props.getProperty(key, defaultValue);
		if (value == null) {
			return value;
		}
		
		String result = parseStringValue(value);
		cache.put(key, result);
		return result;
	}
	
	private String parseStringValue(String value) {
		int startIndex = value.indexOf(PLACEHOLDER_PREFIX);
		if (startIndex != -1) {
			int endIndex = value.indexOf(PLACEHOLDER_SUFFIX, startIndex);
			if (endIndex != -1) {
				String placeholder = value.substring(startIndex + PLACEHOLDER_PREFIX.length(), endIndex);
				
				String varVal = resolveVariable(placeholder);
				
				if (varVal == null) {
					varVal = placeholder;
				}
				return parseStringValue(value.substring(0, startIndex) + varVal + value.substring(endIndex + 1));
			}
		}

		return value;
	}
	
	private String resolveVariable(String name) {
		String value = null;
		if (variables != null) {
			value = variables.get(name);
		}
		if (value == null) {
			value = get(name);
		}
		if (value == null) {
			value = System.getProperty(name);
		}
		return value;
	}
	
	public static int getInteger(String key, int defaultValue) {
		return getInstance()._getInteger(key, defaultValue);
	}
	
	public int _getInteger(String key, int defaultValue) {
		if (cache.containsKey(key)) {
			return (Integer) cache.get(key);
		}

		String value = get(key);
		
		if (value == null) {
			return defaultValue;
		}

		int result = defaultValue;

		try {
			result = Integer.parseInt(value);
		} catch (NumberFormatException e) {}

		cache.put(key, result);
		return result;
	}
	
	public static boolean getBoolean(String key, boolean defaultValue) {
		return getInstance()._getBoolean(key, defaultValue);
	}
	
	public boolean _getBoolean(String key, boolean defaultValue) {
		if (cache.containsKey(key)) {
			return (Boolean) cache.get(key);
		}

		String value = get(key);
		
		if (value == null) {
			return defaultValue;
		}

		boolean result = defaultValue;

		try {
			result = Boolean.parseBoolean(value);
		} catch (NumberFormatException e) {}

		cache.put(key, result);
		return result;
	}
	
	public static long getLong(String key) {
		return getLong(key, 0);
	}
	
	public static long getLong(String key, long defaultValue) {
		return getInstance()._getLong(key, defaultValue);
	}
	
	public long _getLong(String key, long defaultValue) {
		if (cache.containsKey(key)) {
			return (Integer) cache.get(key);
		}

		String value = get(key);
		
		if (value == null) {
			return defaultValue;
		}

		long result = defaultValue;

		try {
			result = Long.parseLong(value);
		} catch (NumberFormatException e) {}

		cache.put(key, result);
		return result;
	}
	
	public static String[] getStringArray(String key, String separator) {
		return getInstance()._getStringArray(key, separator);
	}
	
	public String[] _getStringArray(String key, String separator) {
		if (cache.containsKey(key)) {
			return (String[]) cache.get(key);
		}
		
		String value = get(key);
		
		if (value == null) {
			return new String[0];
		}
		
		return org.springframework.util.StringUtils.split(value, separator);
	}
}
